package cn.itcast.nems.journal.scheduler;

import java.util.List;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import cn.hutool.core.lang.Assert;
import cn.itcast.ic.msplatform.api.model.Dictionary;
import cn.itcast.nems.base.service.DictionaryService;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.account.AccountInfo;
import cn.itcast.nems.employee.dao.entity.Employee;
import cn.itcast.nems.employee.service.EmployeeService;
import cn.itcast.nems.journal.dto.JournalDropoutCreateDTO;
import cn.itcast.nems.journal.dto.JournalDropoutCreateDTO.JournalDropoutTypeEnum;
import cn.itcast.nems.journal.service.JournalDropoutService;
import cn.itcast.nems.studentrecord.dao.entity.JournalDropoutBatchImport;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class BatchImportJournalDropoutHandler {
    private final JournalDropoutBatchImportService journalDropoutBatchImportService;
    private final JournalDropoutService dropoutService;
    private final DictionaryService dictionaryService;
    private final EmployeeService employeeService;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void importDropout(JournalDropoutBatchImport task) {
        JournalDropoutCreateDTO params = new JournalDropoutCreateDTO();
        params.setStudentRecordId(task.getStudentRecordId());
        params.setBizDate(task.getBizDate());
        params.setType(getType(task.getOperatorType()));
        params.setReasonCode(getReasonCode(task.getBizReason()));
        params.setRemark(task.getRemark().trim());
        params.setSpecialFlag(getBooleanFlag(task.getSpecialFlag()));
        params.setInvoiceFlag(getBooleanFlag(task.getInvoiceFlag()));
        params.setLoanFlag(getBooleanFlag(task.getLoanFlag()));
        params.setCompanyCode(getCompanyCode(task.getCompanyName()));
        params.setAmount(task.getAmount());
        params.setDraftFlag(Boolean.FALSE);
        
        setAccount(task.getCreatorEmail());
        String journalId = dropoutService.create(params);
        journalDropoutBatchImportService.finish(task.getId(), journalId);
    }

    /**
     * 
     * 功能描述：是否中文文本转换为布尔值
     *
     * @param flagText 是否的文本
     * @return 布尔值
     * 
     * @author 刘曙
     *
     * @since 2024年3月26日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private Boolean getBooleanFlag(String flagText) {
        return "是".equals(flagText.trim()) ? Boolean.TRUE : Boolean.FALSE;
    }

    /**
     * 
     * 功能描述：中文操作类型转化为枚举对象
     *
     * @param taskOperatorType 导入任务的中文操作类型
     * @return 退学类型的枚举对象
     * 
     * @author 刘曙
     *
     * @since 2024年3月26日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private JournalDropoutTypeEnum getType(String taskOperatorType) {
        if (!StringUtils.hasText(taskOperatorType)) {
            return null;
        }
        
        final String DROPOUT_OPERATE_TYPE = "退学不退费";
        final String DROPOUT_REFUND_OPERATE_TYPE = "退学退费";

        taskOperatorType = taskOperatorType.trim();
        if (DROPOUT_OPERATE_TYPE.equalsIgnoreCase(taskOperatorType)) {
            return JournalDropoutTypeEnum.DROPOUT;
        } else if (DROPOUT_REFUND_OPERATE_TYPE.equalsIgnoreCase(taskOperatorType)) {
            return JournalDropoutTypeEnum.DROPOUT_REFUND;
        }

        throw new IllegalArgumentException("操作类型不正确，请重新填写！！");
    }

    /**
     * 
     * 功能描述：通过公司名称获取公司code
     *
     * @param companyName 公司名称
     * @return 公司code
     * 
     * @author 刘曙
     *
     * @since 2024年3月26日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private String getCompanyCode(final String companyName) {
        if (!StringUtils.hasText(companyName)) {
            return null;
        }
        
        final String DICT_NEMS_COMPANY = "NEMS_COMPANY";
        List<Dictionary> dictionaries = dictionaryService.listByName(DICT_NEMS_COMPANY, companyName.trim());
        if (CollectionUtils.isEmpty(dictionaries)) {
            throw new IllegalArgumentException("公司名称不正确，请重新填写！");
        }
        return dictionaries.get(0).getCode();
    }
    
    /**
     * 
     * 功能描述：获取系统功能上指定的凭单办理业务原因
     *
     * @param journalType 凭单类型
     * @param bizReason 导入任务填写的业务原因
     * @return 业务原因CODE
     * @throws 业务原因不存在时，抛出IllegalArgumentException异常
     * 
     * @author 刘曙
     *
     * @since 2024年3月17日
     *
     * @update:[变更日期YYYY-MM-DD][更改人姓名][变更描述]
     */
    private String getReasonCode(@NonNull String bizReason) {
        final String DICT_JOURNAL_DROPOUT_REASON = "NEMS_JOURNAL_DROPOUT_REASON";
        List<Dictionary> dictionaries = dictionaryService.listByName(DICT_JOURNAL_DROPOUT_REASON, bizReason.trim());
        if (CollectionUtils.isEmpty(dictionaries)) {
            throw new IllegalArgumentException("退学原因不正确，请重新填写！");
        }
        return dictionaries.get(0).getCode();
    }    
    
    /**
     * 发起人登录
     *
     * @param email
     */
    private void setAccount(String creator) {
        Assert.notBlank(creator, "发起人名称不能为空！", creator);
        
        // 通过发起人姓名获取用户
        List<Employee> employees = employeeService.findByName(creator);
        Assert.isTrue(!CollectionUtils.isEmpty(employees) && employees.size()==1, "发起人【{}】不正确，找不到或找到多个员工用户！", creator);
        
        // 登录
        Employee employee = employees.get(0);
        AccountHolder.setAccountInfo(new AccountInfo(employee.getEmail(), employee.getName(), employee.getJobNumber(), ""));
    }
}
